home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TPUG - Toronto PET Users Group
/
TPUG Users Group CD
/
TPUG Users Group CD.iso
/
AMIGA
/
AMICUS
/
AMICUS15.ADF
/
C
/
FM
/
FILE.C
next >
Wrap
C/C++ Source or Header
|
1988-04-20
|
4KB
|
203 lines
/* :ts=8 bk=0
* Filesystem routines (or, How To Find A File The Hard Way)
*/
#include <exec/types.h>
#include <devices/trackdisk.h>
#include "things.h"
extern struct IOExtTD *diskreq;
extern ULONG diskchangecount, *diskbuffer;
findfile (name) /* Traverse the filesystem the hard way */
char *name;
{
register int err;
register char *b, *e;
char str[80];
strcpy (str, name);
if (b = index (str, ':')) /* Ignore device names */
b++;
else
b = str;
while (*b == '/') /* Ignore leading slashes */
b++;
if (!*b) { /* Don't do anything if string is empty */
notice ("Badly formed filename.");
return (0);
}
e = b;
MotorOn ();
GetSector (ROOTBLOCK); /* All paths are relative to the root */
while (e) {
if (!*b) {
notice ("Badly formed filename.");
return (0);
}
if (e = index (b, '/'))
*e = '\0';
if ((err = traverse (b, hash (b))) < 0) {
switch (err) {
case -1:
notice ("Badly formed path.");
break;
case -2:
notice ("File not found.");
break;
}
return (0);
}
if (e) {
skip: b = e+1;
while (*b == '/')
b++;
}
}
drawfile ();
MotorOff ();
return (1);
}
traverse (str, hash) /* Indirect through the disk blocks */
char *str;
int hash;
{
register int block;
register char *file = (char *) &diskbuffer [NAME];
if (diskbuffer [TYPE] == T_SHORT &&
diskbuffer [SECONDARY_TYPE] == ST_FILE)
/* Can't indirect out of a file */
return (-1);
strupper (str);
block = diskbuffer [hash];
for ever {
if (!block)
return (-2); /* No such file */
GetSector ((long) block);
/* Force null termination in case BCPL doesn't do it */
file [*file + 1] = '\0';
strupper (file+1); /* Force to all upper case */
if (!strcmp (str, file+1)) /* Is this it? */
break;
/* This ain't it; traverse hash chain */
block = diskbuffer [HASHCHAIN];
}
return (1);
}
drawfile () /* Draw file's allocated sectors */
{
register int i;
/*
* File control blocks are marked with pen 1, data blocks with pen 2.
*/
marksector (diskbuffer [HEADER_KEY], 1);
if (diskbuffer [TYPE] == T_SHORT &&
diskbuffer [SECONDARY_TYPE] == ST_FILE)
for ever {
for (i=FH_BLOCKLIST; i>=FH_ENDLIST; i--)
if (diskbuffer [i])
marksector (diskbuffer [i], 2);
if (diskbuffer [EXTENSION]) {
marksector (diskbuffer [EXTENSION], 1);
GetSector (diskbuffer [EXTENSION]);
} else
break;
}
}
strupper (str)
register char *str;
{
while (*str) {
*str = toupper (*str);
str++;
}
}
/*
* The following routines were stolen from an RKM example by Bob Peck and
* hacked up a bit.
*/
GetSector (sector)
long sector;
{
LONG offset = sector * BLOCKSIZE;
diskreq -> iotd_Req.io_Length = BLOCKSIZE;
diskreq -> iotd_Req.io_Data = (APTR) diskbuffer;
/* show where to put the data when read */
diskreq -> iotd_Req.io_Command = ETD_READ;
/* check that disk not changed before reading */
diskreq -> iotd_Count = diskchangecount;
/* convert from cylinder, head, sector to byte-offset value to get
* right one (as dos and everyone else sees it)...*/
/* driver reads one CYLINDER at a time (head does not move for
* 22 sequential sector reads, or better-put, head doesnt move for
* 2 sequential full track reads.)
*/
diskreq -> iotd_Req.io_Offset = offset;
DoIO (diskreq);
return (0);
}
MotorOn()
{
/* TURN ON DISK MOTOR ... old motor state is returned in io_Actual */
diskreq -> iotd_Req.io_Length = 1;
/* this says motor is to be turned on */
diskreq -> iotd_Req.io_Command = TD_MOTOR;
/* do something with the motor */
DoIO (diskreq);
return (0);
}
MotorOff()
{
diskreq -> iotd_Req.io_Length = 0;
/* says that motor is to be turned on */
diskreq -> iotd_Req.io_Command = TD_MOTOR;
/* do something with the motor */
DoIO (diskreq);
return (0);
}
/*
* The following code segment was thrown at the USENET by Neil Katin.
* Thanks, Neil.
*/
hash (str)
unsigned char *str;
{
int res;
unsigned char *sp;
unsigned c;
res = strlen (str);
for (sp = str; *sp; sp++) {
c = *sp;
if (c >= 'a' && c <= 'z')
c = c - 'a' + 'A';
res = ((res * 13 + c) & 0x7ff);
}
return (res % 72 + DIR_HASHTAB);
}